import sys
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QTextEdit,
    QCheckBox, QTableWidget, QTableWidgetItem, QWidget, QLabel, QLineEdit, QAbstractItemView
)
from PyQt5.QtCore import QTimer, Qt
import paramiko

class LogViewer(QMainWindow):

    def __init__(self):
        super().__init__()

        # 界面初始化
        self.setWindowTitle("远程日志查看器")
        self.setGeometry(100, 100, 900, 500)
        self.log_data = []  # 存储日志记录
        self.filtered_data = []  # 存储过滤后的日志记录

        # 当前过滤器
        self.filter_options = {
            "Connect": True, "Quit": True, "Execute": True,
            "Prepare": True, "Close": True, "Query": True,
            "Transaction": True, "Error": True, "Warning": True, "Other": True
        }

        # 连接默认信息
        self.remote_host = "10.6.220.92"
        self.port = "10022"
        self.username = "sunri"
        self.password = "111111"
        self.log_file_path = "/var/log/mysql/mysql.log"

        self.init_ui()
        self.timer = QTimer()

    def init_ui(self):
        # 主布局
        main_layout = QVBoxLayout()

        # 配置区域
        config_layout = QHBoxLayout()
        config_layout.addWidget(QLabel("远程服务配置:"))
        config_layout.addWidget(QLabel("IP:"))
        self.host_input = QLineEdit(self.remote_host)
        config_layout.addWidget(self.host_input)

        config_layout.addWidget(QLabel("端口:"))
        self.port_input = QLineEdit(self.port)
        self.port_input.setMaximumWidth(50)
        config_layout.addWidget(self.port_input)

        config_layout.addWidget(QLabel("用户名:"))
        self.username_input = QLineEdit(self.username)
        self.username_input.setMaximumWidth(50)
        config_layout.addWidget(self.username_input)

        config_layout.addWidget(QLabel("密码:"))
        self.password_input = QLineEdit(self.password)
        self.password_input.setEchoMode(QLineEdit.Password)
        config_layout.addWidget(self.password_input)

        config_layout.addWidget(QLabel("日志文件路径:"))
        self.filepath_input = QLineEdit(self.log_file_path)
        self.filepath_input.setMinimumWidth(180)
        config_layout.addWidget(self.filepath_input)

        self.connect_button = QPushButton("获取")
        self.connect_button.clicked.connect(self.start_fetching_logs)
        config_layout.addWidget(self.connect_button)

        main_layout.addLayout(config_layout)

        # 日志操作区
        filter_layout = QHBoxLayout()
        filter_layout.addWidget(QLabel("日志类型过滤:"))
        for log_type in self.filter_options.keys():
            checkbox = QCheckBox(log_type)
            checkbox.setChecked(True)
            checkbox.stateChanged.connect(self.update_filter)
            filter_layout.addWidget(checkbox)

        main_layout.addLayout(filter_layout)

        # 日志显示区
        self.table_log = QTableWidget()
        self.table_log.setColumnCount(4)
        self.table_log.verticalHeader().setVisible(False)
        self.table_log.setHorizontalHeaderLabels(["序号","进程ID", "操作类型", "语句详情"])
        self.table_log.setColumnWidth(0, 50)  # 设置“序号”的宽度为50
        self.table_log.setColumnWidth(1, 50)  # 设置“ID”的宽度为50
        self.table_log.setColumnWidth(2, 100)  # 设置“类型”的宽度为100
        self.table_log.horizontalHeader().setStretchLastSection(True)  # 让“详情”列自适应剩余宽度
        self.table_log.itemClicked.connect(self.show_log_details)          # 添加点击事件处理，显示日志详情
        main_layout.addWidget(self.table_log)  

        # 日志详情区
        details_layout = QHBoxLayout()
        self.details_label = QLabel("日志详情:")
        details_layout.addWidget(self.details_label)
        self.details_view = QTextEdit()
        self.details_view.setReadOnly(True)
        self.details_view.setMaximumHeight(100)
        details_layout.addWidget(self.details_view)
        main_layout.addLayout(details_layout)

        # 主窗口设置
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)

    def start_fetching_logs(self):
        """连接服务器并开始实时获取日志"""
        self.remote_host = self.host_input.text()
        self.port = int(self.port_input.text())
        self.username = self.username_input.text()
        self.password = self.password_input.text()
        self.log_file_path = self.filepath_input.text()
        self.port = int(self.port_input.text())

        try:
            self.ssh = paramiko.SSHClient()
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh.connect(
                self.remote_host, username=self.username, password=self.password, port=self.port
            )

            self.sftp = self.ssh.open_sftp()
            self.timer.timeout.connect(self.fetch_logs)
            self.timer.start(1000)  # 每2秒更新一次日志

        except Exception as e:
            self.details_view.setText(f"连接失败: {str(e)}")

    def fetch_logs(self):
        """实时获取远程日志"""
        try:
            with self.sftp.file(self.log_file_path, 'r') as remote_file:
                lines = remote_file.readlines()

            self.log_data = []
            for idx, line in enumerate(lines):
                parts = line.strip().split(maxsplit=2)
                log_type = parts[1] if len(parts) > 1 else "Other"
                details = parts[2] if len(parts) > 2 else line.strip()
                self.log_data.append({"id": idx + 1, "type": log_type, "details": details})

            self.apply_filter()
            self.scroll_to_bottom()

        except Exception as e:
            self.details_view.setText(f"日志刷新失败: {str(e)}")

    def apply_filter(self):
        """应用过滤器更新显示"""
        self.filtered_data = [
            log for log in self.log_data if self.filter_options.get(log["type"], False)
        ]
        self.update_table()

    def update_filter(self):
        """更新过滤选项"""
        sender = self.sender()
        self.filter_options[sender.text()] = sender.isChecked()
        self.apply_filter()

    def update_table(self):
        """更新日志表格"""
        self.table_log.setRowCount(len(self.filtered_data))
        for row_idx, log in enumerate(self.filtered_data):
            self.table_log.setItem(row_idx, 0, QTableWidgetItem(str(row_idx + 1)))  # 填充“序号”
            self.table_log.setItem(row_idx, 1, QTableWidgetItem(str(log["id"])))   # 填充“ID”
            self.table_log.setItem(row_idx, 2, QTableWidgetItem(log["type"]))      # 填充“类型”
            self.table_log.setItem(row_idx, 3, QTableWidgetItem(log["details"]))  # 填充“详情”

    def scroll_to_bottom(self):
        """将滚动条滑动到底部"""
        self.table_log.scrollToBottom()

    def show_log_details(self, item):
        """显示日志详情"""
        row = item.row()
        log_details = self.filtered_data[row]["details"]
        self.details_view.setText(log_details)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    viewer = LogViewer()
    viewer.show()
    sys.exit(app.exec_())
